define(['AMap', 'lodash', 'jquery', 'AMapUI', 'api'], function (AMap, _, $, AMapUI, api) {
    'use strict';

    var markerCircleDom = '' +
        '<div class="marker-region">' +
        '  <div class="text-wrapper"></div>' +
        '</div>';

    var markerInfoDom = '' +
        '<div class="marker-house-wrapper">' +
        '  <span class="marker-house-price"></span>' +
        '  <span class="marker-house-number"></span>' +
        '</div>';

    var infoWinDom = '' +
        '<div class="win-house-wrapper">' +
        '    <img>' +
        '    <div class="text-wrapper">' +
        '      <h4></h4>' +
        '      <em>/㎡</em>' +
        '      <span>年建</span>' +
        '    </div>' +
        '</div>';

    var utils = {
        throttle: function (fn, delay) {
            var timer = null;
            return function () {
                const context = this;
                const args = arguments;
                clearTimeout(timer);
                timer = setTimeout(function () {
                    fn.apply(context, args);
                }, delay);
            }
        },

        sum: function (key, dataItems) {
            return _.sumBy(dataItems, function (item) {
                return item.dataItem[key];
            });
        },

        average: function (key, dataItems) {
            var res = this.sum(key, dataItems);
            return res !== 0 ? res / dataItems.length : 0;
        }
    };

    var AppMap = {
        name: 'app-map',
        template: '<div class="container-map"><div id="app-map"></div></div>',
        props: {
            queryParams: {
                type: Object,
                default: function () {
                    return {};
                }
            }
        },
        data: function () {
            return {
                mapObj: {},
                distCluster: {},
                markers: [],
                plotData: [],
                mapInfoWin: {},
                showHouseMarkers: false
            }
        },
        computed: {},
        watch: {
            queryParams: {
                deep: true,
                handler: function () {
                    this.fetchMapMarkerData();
                }
            }
        },
        methods: {
            initDistrictCluster: function (DistrictCluster) {
                var that = this;
                this.distCluster = new DistrictCluster({
                    map: this.mapObj, //所属的地图实例
                    //返回数据项中的经纬度位置
                    getPosition: function (item) {
                        return item.position;
                    },
                    topAdcodes: [460100, 460200, 469002, 469024, 469007, 469023, 469005],
                    renderOptions: {
                        featureStyle: {
                            fillStyle: 'rgba(0,0,0,0)',
                            lineWidth: 0,
                            strokeStyle: 'rgba(0,0,0,0)',
                            hoverOptions: {
                                fillStyle: 'rgba(0,0,0,0)'
                            }
                        },
                        //特定区划级别的默认样式
                        featureStyleByLevel: {
                            //全国
                            country: {
                                fillStyle: 'rgba(0,0,0,0)'
                            },
                            //省
                            province: {
                                fillStyle: 'rgba(0,0,0,0)'
                            },
                            //市
                            city: {
                                fillStyle: 'rgba(0,0,0,0)'
                            },
                            //区县
                            district: {
                                fillStyle: 'rgba(0,0,0,0)'
                            }
                        },
                        getClusterMarker: function (feature, dataItems, recycledMarker) {
                            var content = $(markerCircleDom);

                            // 计算平局价格
                            var avgPrice = (utils.average('avgPrice', dataItems) * 0.0001);
                            avgPrice = avgPrice !== 0 ? avgPrice.toFixed(2) : 0;  // 价格为0不保留小数

                            content
                                .find('.text-wrapper')
                                .append(feature.properties.name + '<br>')
                                .append(utils.sum('quantity', dataItems) + '套' + '<br>')
                                .append(avgPrice + '万');

                            return new AMap.Marker({
                                content: content[0]
                            });
                        }
                    }
                });
                this.fetchMapMarkerData();
            },

            geocoder: function (location) {
                var geocoder = new AMap.Geocoder();
                //地理编码,返回地理编码结果
                geocoder.getLocation(location, function (status, result) {
                    if (status === 'complete' && result.info === 'OK') {
                        return result;
                    }
                });
            },

            addHouseMarkers: function () {
                var that = this;

                for (var i = 0; i < this.plotData.length; i++) {
                    var content = $(markerInfoDom);
                    content
                        .find('.marker-house-price')
                        .html((this.plotData[i].avgPrice * 0.0001).toFixed(2) + '万')
                        .parent()
                        .find('.marker-house-number')
                        .html(this.plotData[i].quantity + '套');

                    var mk = new AMap.Marker({
                        position: this.plotData[i].position,
                        content: content[0]
                    });

                    var beforeMkDom;
                    (function (i) {
                        mk.on('click', function (e) {
                            var content = $(infoWinDom);
                            var target = e.target;
                            content
                                .find('img')
                                .attr('src', this.plotData[i].coverUrl)
                                .parent()
                                .find('.text-wrapper h4')
                                .html(this.plotData[i].name)
                                .parent()
                                .find('em')
                                .prepend(this.plotData[i].avgPrice)
                                .parent()
                                .find('span')
                                .prepend(this.plotData[i].buildingYear);

                            window.bus.$emit('update-plot-id', this.plotData[i].id);

                            // 清除之前dom节点的active状态
                            typeof beforeMkDom !== 'undefined' ? beforeMkDom.removeClass('active') : '';

                            var mkDom = $(target.getContent());
                            mkDom.addClass('active');
                            beforeMkDom = mkDom;

                            this.mapInfoWin.setContent(content[0]);
                            this.mapInfoWin.open(this.mapObj, target.getPosition());
                        }, that);
                    }(i));

                    this.markers.push(mk);
                }

                this.mapObj.add(this.markers);
            },

            fetchMapMarkerData: function () {
                var that = this;
                api.fetchMapMarkerData(this.queryParams)
                    .done(function (res) {
                        if (res.IsSuccess) {
                            that.plotData = res.ResultObject;
                            // var beforeCenter = that.mapObj.getCenter();
                            // var beforeZoom = that.mapObj.getZoom();
                            that.distCluster.setData(res.ResultObject);
                            // that.mapObj.setZoomAndCenter(beforeZoom, beforeCenter);
                        }
                    })
            },
            bindEvents: function () {
                var that = this;
                this.distCluster.on('clusterMarkerClick', function (event, record) {
                    var level = record.feature.properties.level;
                    var center = record.feature.properties.center;
                    if (level === 'district') {
                        that.mapObj.setZoomAndCenter(15, center);
                    }

                    window.bus.$emit('update-adcode', record.adcode);
                });

                this.mapObj.on('zoomchange', function () {
                    if (that.mapObj.getZoom() >= 15 && !that.showHouseMarkers) {
                        that.showHouseMarkers = true;
                        that.distCluster.hide();
                        that.addHouseMarkers();
                    } else if (that.mapObj.getZoom() < 15 && that.showHouseMarkers) {
                        that.showHouseMarkers = false;
                        that.distCluster.show();
                        that.mapObj.remove(that.markers);
                        that.mapInfoWin.close();
                    }
                });

                this.mapObj.on('moveend', utils.throttle(function () {
                    that.mapObj.getCity(function (res) {
                        window.bus.$emit('map-move', res);
                    });
                }), 400);

                window.bus.$on('autocomplete-select', function (data) {
                    console.log(data);
                    that.mapObj.setZoomAndCenter(16, data.poi.location);
                });
            },

            init: function () {
                var that = this;
                this.mapObj = new AMap.Map('app-map', {
                    resizeEnable: true,
                    zoom: 10,
                    center: [110.358312, 20.016729]
                });

                AMapUI.loadUI(['geo/DistrictCluster'], function (DistrictCluster) {
                    that.initDistrictCluster(DistrictCluster);
                    that.bindEvents();
                });

                this.mapInfoWin = new AMap.InfoWindow({
                    isCustom: true,
                    offset: new AMap.Pixel(30, -40)
                });
            }
        },
        mounted: function () {
            this.init();
        }
    };

    return AppMap;
});
